#include "serveur.h" 
#include "interface/interface.h"
#include "temps/cycle.h"
#include "reseau/synchro_serveur.h"
#include <sstream>
#include <string>

extern const char connexion_annulee[] = "Connexion annulee";

void serveur::nouveau_depassement() {
	lbl_depassements_.visible(true);
	std::ostringstream os;
	os << (++nb_depassements_) << " depassement" << (nb_depassements_>1?"s.":".");
	lbl_depassements_.texte(os.str());
}

serveur::serveur(int l) throw(erreur) : latence_exigee_(l), lbl_pbs_connexion_("Attente d'une connexion...", false, 80, 58), img_annuler_("annuler.png", 189, 77), btn_annuler_(img_annuler_), dispatcheur_(latence_exigee_), lbl_depassements_("Aucun depassement", false, 80, 18, false), nb_depassements_(0) {
	while(!module_interface::instance().doit_quitter() && !serveur_.occupe() && !btn_annuler_()) {
		cycle<100> c;
		module_interface::instance().actualiser_affichage();
		module_interface::instance().traiter_evenements();
		serveur_.accepter_connexions();
	}
	
	if(module_interface::instance().doit_quitter() || btn_annuler_())
		throw une_erreur<connexion_annulee>();
	
	lbl_pbs_connexion_.texte("Synchronisation avec le client...");
	img_annuler_.visible(false); 
	module_interface::instance().actualiser_affichage();
	// On démarre la synchronisation maintenant qu'on est connecté
	synchronisation<serveur_reseau> protocole_sync_(serveur_);
	
	std::ostringstream os;
	os << "OK. sante=" << (int)(protocole_sync_.sante_connexion()*100) << "%, tr=" << protocole_sync_.roundtrip_moyen()/2 << "ms, d=" << doc_emmett_brown::instance().delta(0) << "ms";
	
	lbl_pbs_connexion_.texte(os.str());
	img_annuler_.visible(true); 
	module_interface::instance().actualiser_affichage();
	
	// Le serveur fait son petit jeu
	instantane_du_piano recu;
	int nb_cycles = 0;
	temps::type_temps seuil_tolerance = 25;
	
	while(!module_interface::instance().doit_quitter() && !btn_annuler_() && serveur_.occupe()) {
		++nb_cycles;
		cycle<2> c;
		if(nb_cycles == 60) {
			nb_cycles = 0;
			module_interface::instance().actualiser_affichage();
		}
		if(nb_cycles == 30)
			module_interface::instance().traiter_evenements();
		
		if(serveur_.recepteur().recevoir_udp(recu))
			dispatcheur_.deposer(recu);
		
		if(dispatcheur_.sons_a_jouer())
			if(doc_emmett_brown::instance().est_en_train_de_se_produire(dispatcheur_.moment_prochain_son_a_jouer() + latence_exigee_, seuil_tolerance)) {
				//temps::type_temps tpsd = dispatcheur_.moment_prochain_son_a_jouer() + latence_exigee_;
				//temps::type_temps tpsl = doc_emmett_brown::instance().delta(tpsd);
				//std::cout << "Son envoyé  : (distant)" << dispatcheur_.moment_prochain_son_a_jouer() << "ms / (local)" << doc_emmett_brown::instance().delta(dispatcheur_.moment_prochain_son_a_jouer()) << "ms" << std::endl;
				//std::cout << "Son à jouer : (distant)" << tpsd << "ms / (local)" << tpsl << "ms / (now)" << temps::maintenant() << "ms / (diff)" << (temps::maintenant() - tpsl) << "ms" << std::endl;
				lecture_son l = dispatcheur_.prochain_son_a_jouer();
				audio_.jouer(l);
			} else if(doc_emmett_brown::instance().est_deja_passe(dispatcheur_.moment_prochain_son_a_jouer() + latence_exigee_ + seuil_tolerance)) {
				// on pourrait faire : dispatcheur_.oublier_prochain_son();
                                // mais on préfère jouer le son histoire de
                                lecture_son l = dispatcheur_.prochain_son_a_jouer();
				audio_.jouer(l);
				nouveau_depassement();
			}
	}
}
